package com.forpastime.forutils.utils;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.io.Serializable;
import java.time.Duration;
/**
 * @author linkanyway
 * @version 1.0
 * @name LettuceRedisConfig
 * @description TODO
 * @date 2022/01/11 22:44
 */
@Configuration
@ConfigurationProperties("spring.redis")
@Slf4j
public class RedisAutoConfiguration {
    @Value("${spring.redis.host}")
    private String hostName;
    @Value("${spring.redis.password}")
    private String password;
    @Value("${spring.redis.port}")
    private int port;
    @Value("${spring.redis.database}")
    private int database;
    @Value("${spring.redis.lettuce.pool.maxIdle}")
    private int maxIdle;
    @Value("${spring.redis.lettuce.pool.minIdle}")
    private int minIdle;
    @Value("${spring.redis.lettuce.pool.maxWaitMillis}")
    private int maxWaitMillis;
    @Value("${spring.redis.lettuce.pool.maxTotal}")
    private int maxTotal;
    /**
     * LettuceConnectionFactory
     *
     * @return
     */
    @Bean
    public LettuceConnectionFactory redisConnectionFactory() {
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration ();
        redisStandaloneConfiguration.setHostName(hostName);
        redisStandaloneConfiguration.setPort(port);
        redisStandaloneConfiguration.setPassword(password);
        redisStandaloneConfiguration.setDatabase(database);
        GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig ();
        poolConfig.setMaxIdle(maxIdle);
        poolConfig.setMinIdle(minIdle);
        poolConfig.setMaxWaitMillis(maxWaitMillis);
        poolConfig.setMaxTotal(maxTotal);
        LettucePoolingClientConfiguration lettucePoolingClientConfiguration =
                LettucePoolingClientConfiguration.builder ().commandTimeout (Duration.ofSeconds (10)).shutdownTimeout (Duration.ZERO).poolConfig (poolConfig).build ();
        LettuceConnectionFactory lettuceConnectionFactory =
                new LettuceConnectionFactory (redisStandaloneConfiguration, lettucePoolingClientConfiguration);
        lettuceConnectionFactory.setShareNativeConnection (false);
        System.out.printf("执行到Lettuce");

        return lettuceConnectionFactory;
    }
    /**
     * RedisTemplate
     *
     * @param connectionFactory
     * @return
     */
    @Bean
    public RedisTemplate redisTemplate(@Autowired LettuceConnectionFactory connectionFactory) {
        RedisTemplate<String, Serializable> redisTemplate = new RedisTemplate<> ();
        redisTemplate.setKeySerializer (new StringRedisSerializer ());
        redisTemplate.setValueSerializer (new GenericJackson2JsonRedisSerializer ());
        redisTemplate.setConnectionFactory (connectionFactory);
        log.error("被引用"+connectionFactory.getHostName()+connectionFactory.getPassword());
        return redisTemplate;
    }
    /**
     * @param factory
     * @return
     */
    @Bean
    public StringRedisTemplate configStringRedisTemplate(@Autowired LettuceConnectionFactory factory) {
        StringRedisTemplate template = new StringRedisTemplate (factory);
        template.setEnableTransactionSupport (true);
        ObjectMapper mapper;
        GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer ();
        template.setValueSerializer (new StringRedisSerializer ());
        template.setKeySerializer (new StringRedisSerializer ());
        template.setHashKeySerializer (new StringRedisSerializer ());
        template.setHashValueSerializer (new StringRedisSerializer ());
        template.afterPropertiesSet ();
        return template;
    }
}
